using System;
using System.Web;
using System.Web.Configuration;

namespace Pegasus.Web.Security.SecureWebPage
{

	/// <summary>
	/// Hooks the application's BeginRequest event in order to request the current 
	/// page securely if specified in the configuration file.
	/// </summary>
	public class SecureWebPageModule : IHttpModule {

		/// <summary>
		/// Initializes an instance of this class.
		/// </summary>
		public SecureWebPageModule() {
		}

		/// <summary>
		/// Disposes of any resources used.
		/// </summary>
		public void Dispose() {
			// No resources were used.
		}

		/// <summary>
		/// Initializes the module by hooking the application's BeginRequest event if indicated by the config settings.
		/// </summary>
		/// <param name="application">The HttpApplication this module is bound to.</param>
		public void Init(HttpApplication application) {
			// Get the settings for the secureWebPages section.
			SecureWebPageSettings Settings = WebConfigurationManager.GetSection("secureWebPages") as SecureWebPageSettings;
			if (Settings != null && Settings.Mode != SecureWebPageMode.Off) {
				// Store the settings in application state for quick access on each request.
				application.Application["SecureWebPageSettings"] = Settings;

				// Add a reference to the private Application_BeginRequest handler for the
				// application's BeginRequest event.
				application.BeginRequest += (new EventHandler(this.Application_BeginRequest));
                application.EndRequest += (new EventHandler(this.Application_EndRequest));
			}
		}

		/// <summary>
		/// Handle the application's BeginRequest event by requesting the current
		/// page securely, if specified.
		/// </summary>
		/// <param name="source">The source of the event.</param>
		/// <param name="e">EventArgs passed in.</param>
		private void Application_BeginRequest(Object source, EventArgs e) {
			// Cast the source as an HttpApplication instance.
			HttpApplication Application = (HttpApplication)source;

			// Retrieve the settings from application state.
			SecureWebPageSettings Settings = (SecureWebPageSettings)Application.Application["SecureWebPageSettings"];

			// Evaluate the response against the settings.
			SecurityType Secure = RequestEvaluator.Evaluate(Application.Request, Settings);

			// Take appropriate action.
			if (Secure == SecurityType.Secure)
				SSLHelper.RequestSecurePage(Settings);
			else if (Secure == SecurityType.Insecure)
				SSLHelper.RequestUnsecurePage(Settings);
		}

        /// <summary>
        /// Handle the application's EndRequest event by ensuring that all cookies that are set
        /// get set with the proper cookie domain, thereby ensuring that the cookies are visible to
        /// both secure and nonsecure domains.
        /// </summary>
        /// <param name="source">The source of the event.</param>
        /// <param name="e">EventArgs passed in.</param>
        private void Application_EndRequest(Object source, EventArgs e)
        {
            // Cast the source as an HttpApplication instance.
            HttpApplication Application = (HttpApplication)source;

            // Retrieve the settings from application state.
            SecureWebPageSettings Settings = (SecureWebPageSettings)Application.Application["SecureWebPageSettings"];

            // Ensure that the cookies are visible to both the secure and nonsecure domains.
            SSLHelper.EnsureCookieVisibility(Settings);
        }
	}

}
